#include "mid_ringbuf.h"

int reset_rbuf(ringbuf *rbuf)
{
	//rbuf->size=0;
	rbuf->pwrite=0;
	rbuf->pread=0;
	rbuf->full=0;
	rbuf->empty =0;
	rbuf->lengthsave= 0;
	rbuf->leave_frame =0;
	rbuf->rf_index =0;
	rbuf->wf_index =0;
	return 0;
}
int rbuf_initial(ringbuf *rbuf,uint32_t size)
{
	int i=0;
	rbuf->size=size;
	rbuf->pwrite=0;
	rbuf->pread=0;
	rbuf->full=0;
	rbuf->empty =0;
	rbuf->lengthsave= 0;
	rbuf->leave_frame =0;
	rbuf->rf_index =0;
	rbuf->wf_index =0;
	for(i=0;i<MAX_FRAME_CNT;i++)rbuf->leave_frame_len[i]=0;
	rbuf->pdata = (uint8_t*)malloc(size);
	if(!rbuf->pdata)
	{
		printf("rbuf_initial malloc failed \r\n");
		return -1;
	}
	memset(rbuf->pdata,0,size);

	return 0;
}
int rbuf_uninitial(ringbuf *rbuf)
{
	if(rbuf->pdata)
	{
		free(rbuf->pdata);
		return 0;
	}

	return -1;
}
uint32_t write_rbuf(ringbuf *rbuf,uint8_t *data,uint32_t length)
{
    uint32_t i;
    uint32_t save_real;
	uint32_t actsavelength1,actsavelength2;

	if(length == 0 || !data || !rbuf)
	{
		//printf("write_rbuf len=%d,data=%8x,rbuf=%8x\r\n",length,(int)data,(int)rbuf);
		return 0;
	}

	save_real = length;
	// save now
	if ((rbuf->pwrite + save_real)>MAX_RINGBUF_LEN)
	{
		
		actsavelength1= MAX_RINGBUF_LEN-rbuf->pwrite;
		actsavelength2  = save_real-actsavelength1;
			
		for(i=0;i<actsavelength1;i++)
		{
			rbuf->pdata[rbuf->pwrite] = data[i];
			rbuf->pwrite += 1;
		}
		for(i=0;i<actsavelength2;i++)
		{
			rbuf->pdata[i] = data[i+actsavelength1];
			
		}
		rbuf->pwrite =actsavelength2;
	}
	else
	{
		for(i=0;i<save_real;i++)
		{
		  rbuf->pdata[rbuf->pwrite] = data[i];
		  rbuf->pwrite += 1;
		}

		rbuf->pwrite = MOD_RINGBUF_LEN(rbuf->pwrite);
	}
	
	rbuf->lengthsave = rbuf->lengthsave + save_real;
		
	return save_real;

}
int move_rbuf_len(ringbuf *rbuf,int len)
{
    rbuf->pread += len;
    rbuf->pread = MOD_RINGBUF_LEN(rbuf->pread);
	rbuf->lengthsave = rbuf->lengthsave - len;
    return len;
}
uint32_t read_rbuf(ringbuf *rbuf,uint8_t *data,uint32_t length)
{
    uint32_t i;
    uint32_t real_pop=0;
    uint32_t actsavelength1,actsavelength2;
    if(length == 0 || !data || !rbuf)
	{
		//printf("read_rbuf len=%d,data=%8x,rbuf=%8x\r\n",length,(int)data,(int)rbuf);
		return 0;
	}
	// Pop now
        real_pop = length;
	
	if ((rbuf->pread + real_pop)>MAX_RINGBUF_LEN)
	{
		
		actsavelength1= MAX_RINGBUF_LEN-rbuf->pread;
		actsavelength2  = real_pop-actsavelength1;

		for(i=0;i<actsavelength1;i++)
		{
		  data[i] = rbuf->pdata[rbuf->pread];
		  rbuf->pread += 1;
		}
		for(i=0;i<actsavelength2;i++)
		{
		  data[i+actsavelength1] = rbuf->pdata[i];
		}
		rbuf->pread = actsavelength2;
	}
	else
	{
		for(i=0;i<real_pop;i++)
		{
		    data[i] = rbuf->pdata[rbuf->pread];
	  	    rbuf->pread = rbuf->pread+1;
		}

		rbuf->pread = MOD_RINGBUF_LEN(rbuf->pread);
	}
	
	rbuf->lengthsave = rbuf->lengthsave - real_pop;
		

    return real_pop;

}
uint32_t get_leavesave(ringbuf *rbuf)
{
	return  (rbuf->lengthsave);
}
uint32_t free_space(ringbuf *rbuf)
{
   return  (MAX_RINGBUF_LEN - rbuf->lengthsave);
}
uint8_t is_rbuf_empty(ringbuf *rbuf)
{
    return rbuf->lengthsave == 0;
}
uint8_t is_rbuf_full(ringbuf *rbuf)
{
    return MAX_RINGBUF_LEN == rbuf->lengthsave;
}
int8_t get_frame_cnt(ringbuf *rbuf)
{
     return rbuf->leave_frame;
}
uint8_t is_frame_cnt_full(ringbuf *rbuf)
{
    if(rbuf->leave_frame>=MAX_FRAME_CNT) 
		return 1;
    else 
		return 0;
}
uint8_t push_frame(ringbuf *rbuf,uint32_t length)
{
   rbuf->leave_frame_len[rbuf->wf_index] = length;
   rbuf->wf_index++;
   if(rbuf->wf_index >= MAX_FRAME_CNT)
   {
   	rbuf->wf_index = 0;
   }
   rbuf->leave_frame++;
   
   if(rbuf->leave_frame > MAX_FRAME_CNT)
   {
	 rbuf->leave_frame = MAX_FRAME_CNT;
	 //printf("push_frame error\r\n");
   }

   return rbuf->leave_frame;
    
}
uint32_t pop_frame_len(ringbuf *rbuf)
{
  uint32_t len=0;

  len = rbuf->leave_frame_len[rbuf->rf_index];
  rbuf->rf_index++;
  if(rbuf->rf_index >= MAX_FRAME_CNT)
  {
  	rbuf->rf_index = 0;
  }
  rbuf->leave_frame--;

  if(rbuf->leave_frame > MAX_FRAME_CNT)
  {
  	rbuf->leave_frame = 0;
  	//printf("pop_frame_len error\r\n");
  }
  return len;
}
uint8_t is_frame_empty(ringbuf *rbuf)
{
	return rbuf->leave_frame == 0;
}
uint8_t is_frame_full(ringbuf *rbuf)
{
	return rbuf->leave_frame == MAX_FRAME_CNT;
}

